// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-11-13

#ifndef __BASE_LIST_H_COMMON_SVR_BASE__
#define __BASE_LIST_H_COMMON_SVR_BASE__

#pragma once

namespace JoyServer
{
//##ModelId=44CEFAD10138
template<typename NodeType>
class CJoyDualList
{
protected:
	//##ModelId=44CEFAD1013A
    NodeType*   m_head;
	//##ModelId=44CEFAD1013B
    NodeType*   m_tail;
	//##ModelId=44CEFAD10148
    UINT    m_count;
public:
	//##ModelId=44CEFAD10149
    CJoyDualList():
        m_head(NULL),
        m_tail(NULL),
        m_count(0)
    {
    }
	//##ModelId=44CEFAD1014A
    ~CJoyDualList()
    {
        RemoveAll();
    }

	//##ModelId=44CEFAD1014B
    void AddTail(NodeType* pNode)
    {
        pNode->m_prev   = m_tail;
        pNode->m_next   = NULL;
        if(m_tail != NULL)
        {
            m_tail->m_next  = pNode;
        }
        else
        {
            m_head  = pNode;
        }
        m_tail  = pNode;
        ++ m_count;
    }
	//##ModelId=44CEFAD1014D
    void AddHead(NodeType* pNode)
    {
        pNode->m_next   = m_head;
        pNode->m_prev   = NULL;
        if(m_head != NULL)
        {
            m_head->m_prev  = pNode;
        }
        else
        {
            m_tail  = pNode;
        }
        m_head  = pNode;
        ++ m_count;
    }
	//##ModelId=44CEFAD1014F
    void RemoveHead()
    {
        delete DetachHead();
    }
	//##ModelId=44CEFAD10157
    void RemoveTail()
    {
        delete DetachTail();
    }
	//##ModelId=44CEFAD10158
    void RemoveAll()
    {
        while(m_head != NULL)
        {
            NodeType* pNode = m_head;
            m_head = m_head->m_next;
            delete pNode;
        }
        m_head = NULL;
        m_tail = NULL;
        m_count= 0;
    }
	//##ModelId=44CEFAD10159
    void Remove(NodeType* pNode)
    {
        Detach(pNode);
        delete pNode;
    }
	//##ModelId=44CEFAD1015B
    void Detach(NodeType* pNode)
    {
        NodeType* pNext = pNode->m_next;
        NodeType* pPrev = pNode->m_prev;
        pNode->m_next   = NULL;
        pNode->m_prev   = NULL;
        if(pNext != NULL)
        {
            pNext->m_prev = pPrev;
        }
        else
        {
            m_tail = pPrev;
        }
        if(pPrev != NULL)
        {
            pPrev->m_next = pNext;
        }
        else
        {
            m_head = pNext;
        }
    }
	//##ModelId=44CEFAD1015D
    NodeType* DetachHead()
    {
        if(m_head == NULL)
        {
            return NULL;
        }
        NodeType* pNode = m_head;
        m_head = m_head->m_next;
        if(m_head != NULL)
        {
            m_head->m_prev = NULL;
        }
        else
        {
            m_tail = NULL;
        }
        pNode->m_next = NULL;
        -- m_count;
        return pNode;
    }
	//##ModelId=44CEFAD1015E
    NodeType* DetachTail()
    {
        if(m_tail == NULL)
        {
            return NULL;
        }
        NodeType* pNode = m_tail;
        m_tail = m_tail->m_prev;
        if(m_tail != NULL)
        {
            m_tail->m_next = NULL;
        }
        else
        {
            m_head = NULL;
        }
        pNode->m_prev = NULL;
        -- m_count;
        return pNode;
    }
	//##ModelId=44CEFAD1015F
    NodeType* GetHead()
    {
        return m_head;
    }
	//##ModelId=44CEFAD10167
    NodeType* GetTail()
    {
        return m_tail;
    }

	//##ModelId=44CEFAD10168
    UINT GetCount() const
    {
        return m_count;
    }
	//##ModelId=44CEFAD1016A
    bool IsEmpty() const
    {
        return m_count == 0;
    }
};

} // namespace JoyServer

#endif  // __BASE_LIST_H_COMMON_SVR_BASE__
